#include <semaphore>
#include <mutex>
#include <queue>
#include <thread>
#include <iostream>

// 总任务数
constexpr int kItems = 10;

// 信号量：表示“可消费任务”的数量；初始为 0
std::counting_semaphore<> sem(0);

// 互斥锁保护队列与 done
std::mutex m;

// 共享队列
std::queue<int> buffer;

// 结束标志
bool done = false;

void producer() {
    for (int i = 0; i < kItems; ++i) {
        {
            std::lock_guard<std::mutex> lg(m); // 将元素压入队列
            buffer.push(i);
        }
        sem.release(); // 增加一个可消费资源
    }

    {
        std::lock_guard<std::mutex> lg(m);
        done = true; // 设定完成标记
    }
    sem.release(); // 额外 release，确保消费者从 sem.acquire() 返回并检查 done
}

void consumer() {
    while (true) {
        sem.acquire(); // 等待可消费资源或结束通知

        std::lock_guard<std::mutex> lg(m);
        if (!buffer.empty()) {
            int item = buffer.front();
            buffer.pop();
            std::cout << "consume " << item << '\n';
        } else if (done) {
            // 如果队列空且 done 为真，说明生产者结束 -> 退出
            break;
        }
        // 若队列空但 done 还未设置，则表示“被额外释放”唤醒，继续循环等待
    }
}

int main() {
    std::thread t1(producer);
    std::thread t2(consumer);
    t1.join();
    t2.join();
}